package com.bluesky.admin.controller.monitor;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bluesky.common.Constants;
import com.bluesky.common.annotation.Log;
import com.bluesky.common.bo.LoginUser;
import com.bluesky.common.config.AppConfig;
import com.bluesky.common.exception.DemoModeException;
import com.bluesky.common.redis.RedisUtils;
import com.bluesky.common.result.R;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 在线用户 前端控制器
 * </p>
 *
 * @author Kevin
 */
@RestController
@RequestMapping("/monitor/online")
public class OnlineUserController {

    @Resource
    RedisUtils redisUtils;

    /**
     * 分页查询
     */
    @GetMapping("/page")
    @PreAuthorize("@ss.hasPermission('monitor:online:page')")
    @Log(title = "在线用户分页查询")
    public R page(Page reqPage, String username) {
        Collection<String> keys = redisUtils.keys(String.format(Constants.USER_TOKEN_TPL, "*"));
        List<LoginUser> loginUserList;
        if (StrUtil.isNotBlank(username)) {
            loginUserList = keys.stream().map(item -> (LoginUser) redisUtils.get(item))
                    .filter(item -> StrUtil.contains(item.getUsername(), username))
                    .sorted(Comparator.comparing(LoginUser::getLoginTime).reversed())
                    .collect(Collectors.toList());
        } else {
            loginUserList = keys.stream().map(item -> (LoginUser) redisUtils.get(item))
                    .sorted(Comparator.comparing(LoginUser::getLoginTime).reversed())
                    .collect(Collectors.toList());
        }

        IPage<LoginUser> page = new Page<>(reqPage.getCurrent(), reqPage.getSize(), loginUserList.size());
        if (page.getPages() > 0) {
            int fromIndex = (int) ((page.getCurrent() - 1) * page.getSize());
            int toIndex = page.getCurrent() == page.getPages() ? (int) page.getTotal() : (int) (fromIndex + page.getSize());
            page.setRecords(loginUserList.subList(fromIndex, toIndex));
        }
        return R.success(page);
    }

    /**
     * 强制退出
     */
    @PostMapping("/forceLogout")
    @PreAuthorize("@ss.hasPermission('monitor:online:forceLogout')")
    @Log(title = "在线用户强制退出")
    public R forceLogout(@RequestParam String token) {
        if (AppConfig.isDemoEnabled()) {
            throw new DemoModeException();
        }
        redisUtils.del(String.format(Constants.USER_TOKEN_TPL, token));
        return R.success();
    }

}
